<?php
// +----------------------------------------------------------------------+
// | Author:  Evgeny Leontev <eleontev@gmail.com>                         |
// | Copyright (c) 2005 Evgeny Leontev                                    |
// +----------------------------------------------------------------------+
// | This source file is free software; you can redistribute it and/or    |
// | modify it under the terms of the GNU Lesser General Public           |
// | License as published by the Free Software Foundation; either         |
// | version 2.1 of the License, or (at your option) any later version.   |
// |                                                                      |
// | This source file is distributed in the hope that it will be useful,  |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
// | Lesser General Public License for more details.                      |
// +----------------------------------------------------------------------+

class TreeHelper
{
	
	var $raw_ar = array();
	var $tree_ar = array();
	
	
	function setItem($id, $parent_id, $more_items) {
		$this->setRawItem($id, $parent_id, $more_items);
		$this->setTreeItem($id, $parent_id);
	}
	
	
	function setRawItem($id, $parent_id, $more_items) {
		$this->raw_ar[$id]['parent_id'] = $parent_id;
		foreach($more_items as $k => $v) {
			$this->raw_ar[$id][$k] = $v;
		}
		
	}
	
	function setTreeItem($id, $parent_id, $more_items = false) {
		if($more_items) {
			$this->tree_ar[$parent_id][$id] = $more_items;
		} else {
			$this->tree_ar[$parent_id][$id] = $id;
		}
	}
	
	
	function &getRawArray() {
		return $this->raw_ar;
	}
	
	
	function &getTreeArray() {
		return $this->tree_ar;
	}
 
 
	// return array (one dimensional) to use to generate anithing
	function &getTreeHelper($parent_id = 0, $level = 0, $ar = array()) {
		return TreeHelperUtil::getTreeHelper($this->tree_ar, $parent_id, $level, $ar);
	}

	
	// return array with all parent to id
	function &getParentsById($id, $label = 'id', $parent_key = 'parent_id', $ar = false) {
		return TreeHelperUtil::getParentsById($this->raw_ar, $id, $label, $parent_key, $ar );
	}
	
	
	// return array with all parent to id
	function &getChildsById($id, $label = 'id', $parent_key = 'parent_id', $ar = array()) {
		return TreeHelperUtil::getChildsById($this->tree_ar, $id, $label, $parent_key, $ar);
	}
}


class TreeHelperUtil
{
	
	// return array with all parent to id, $arr should be in simple format
	function &getParentsById($arr, $id, $label = 'id', $parent_key = 'parent_id', $ar = array()) {
		
		if(isset($arr[$id])) {
			$parent_id = $arr[$id][$parent_key];
			$ar[$id] = ($label == 'id') ? $id : $arr[$id][$label];
			$ar = TreeHelperUtil::getParentsById($arr, $parent_id, $label, $parent_key, $ar);
		} else {
			$ar = array_reverse($ar, true);
		}
		
		//ksort($ar);
		return $ar;
	}

	
	function getTopParent($arr, $id, $top_parent_id = 0, $label = 'id', $parent_key = 'parent_id') {
		
		if(isset($arr[$id])) {
			$parent_id = $arr[$id][$parent_key];
			if($parent_id == $top_parent_id) {
				return $id;
			} else {
				$ar[$id] = ($label == 'id') ? $id : $arr[$id][$label];
				$val = TreeHelperUtil::getTopParent($arr, $parent_id, $top_parent_id, $label, $parent_key);
			}
			
		} else {
			$val = $id;
		}
		
		//ksort($ar);
		return $val;		
	}
	
	
	// return array with all childs to id in format id => id, 
	// $arr should be in tree format
	function &getChildsById($arr, $id, $label = 'id', $parent_key = 'parent_id', $ar = array()) {
		
		if(!isset($arr[$id])) { $a = array(); return $a; }
		
		foreach($arr[$id] as $_child_id => $_id) {
			//$ar[] = $_id;
			$ar[] = ($label == 'id') ? $_id : $arr[$id][$_child_id][$label];
			
			if(isset($arr[$_child_id])) {
				$ar = &TreeHelperUtil::getChildsById($arr, $_child_id, $label, $parent_key, $ar);
			}
		}
		
		return $ar;
	}
	
	
	// return array (one dimensional) to use to generate anithing
	// in format id => level, $arr should be in tree format
	function &getTreeHelper($arr, $parent_id = 0, $level = 0, $ar = array()) {
		
		if(!isset($arr[$parent_id])) { return array(); }
		
		foreach($arr[$parent_id] as $_parent_id => $_id) {
			$ar[$_id] = $level;

			if(isset($arr[$_parent_id])) {
				$ar = &TreeHelperUtil::getTreeHelper($arr, $_parent_id, $level+1, $ar);
			}
		}
		
		return $ar;
	}
}




//$row[] = array('id'=>0,'parent_id'=>-1,'url'=>'index.php','name'=>'0');
/*
$row[1] = array('id'=>1,'parent_id'=>0,'url'=>'index.php','name'=>'0.1');
$row[2] = array('id'=>2,'parent_id'=>0,'url'=>'any.php','name'=>'0.2');
$row[3] = array('id'=>3,'parent_id'=>0,'url'=>'contact.php','name'=>'0.3');
$row[4] = array('id'=>4,'parent_id'=>1,'url'=>'doctor.php','name'=>'1.1');
$row[5] = array('id'=>5,'parent_id'=>1,'url'=>'doctor1.php','name'=>'1.2');
$row[6] = array('id'=>6,'parent_id'=>4,'url'=>'doctor2.php','name'=>'1.1.2');


$tree = new TreeHelper;
foreach($row as $k => $v) {
	$tree->setTreeItem($v['id'], $v['parent_id']);
}

echo "<pre>"; print_r($tree); echo "</pre>";

$ar = $tree->getTreeArray();
$ar = TreeHelperUtil::getChildsById($ar, 1);
echo "<pre>"; print_r($ar); echo "</pre>";
*/



/*
$tree = new TreeHelper;

$tree->setItem(1, 0, array('name'=>'name_1'));
$tree->setItem(2, 0, array('name'=>'name_2'));
$tree->setItem(3, 0, array('name'=>'name_3'));
$tree->setItem(4, 1, array('name'=>'name_1.1'));
$tree->setItem(5, 4, array('name'=>'name_1.1'));
$tree->setItem(6, 5, array('name'=>'name_1.1'));
$tree->setItem(7, 6, array('name'=>'name_1.1'));
*/


/*
$tree->setTreeItem(1, 0, array('name'=>'name_1'));
$tree->setTreeItem(2, 0, array('name'=>'name_2'));
$tree->setTreeItem(3, 0, array('name'=>'name_3'));
$tree->setTreeItem(4, 1, array('name'=>'name_1.1'));
$tree->setTreeItem(5, 4, array('name'=>'name_1.1'));
$tree->setTreeItem(6, 5, array('name'=>'name_1.1'));
$tree->setTreeItem(7, 6, array('name'=>'name_1.1'));
*/




//echo "<pre>"; print_r($tree->getRawArray()); echo "</pre>";

//$ar1 =& $tree->getTreeHelper();
//$ar =& $tree->getParentsById(5);
//$ar =& TreeHelperUtil::getChildsById($tree->getTreeArray(), 1);

//$ar =& $tree->getChildsById(4);

//echo TreeHelperUtil::getTopParent($tree->getRawArray(), 2);

//echo "<pre>"; print_r($ar1); echo "</pre>";
//echo "<pre>"; print_r($ar); echo "</pre>";
//echo "<pre>"; print_r($tree); echo "</pre>";




/*
# SQL EXAMPLE
SELECT s1.id, s1.parent_id, s1.module_name, s1.menu_name
FROM s_priv_module s
LEFT JOIN s_priv_module s1 ON s.id = s1.parent_id
WHERE s.id = s1.parent_id
AND s1.parent_id = 1
*/



/*
function createSelect($array, $pref, $parent = 0, $level = 0) {

	foreach($array[$parent] as $k => $v) { 
		if ($k == "0"){
			@$html .= "<option value=\"".$k."\" id=\"".$v['id']."\">".strtoupper($v['option'])."</option>\n";
		} else {
			$pre = str_repeat($pref, $level);
			@$html .= "<option value=\"".$k."\" id=\"".$v['id']."\">".$pre.$v['option']."</option>\n";
		}

		if(isset($array[$k])){
			$html .= createSelect($array, $pref, $k, $level+1);
		}
	}
	return $html;
}
*/
?>
